namespace DbUp.ScriptProviders
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Text;

    /// <summary>
    /// 
    /// </summary>
    public sealed class FolderScriptProvider
        : IScriptProvider
    {
        /// <summary>
        /// Default search pattern for sql-file extension.
        /// </summary>
        private const string FILE_SEARCH_PATTERN = "*.sql";

        /// <summary>
        /// Member for path from where to load files.
        /// </summary>
        private readonly string _Path;

        /// <summary>
        /// Member for expression by that sql-files to load are being filtered.
        /// </summary>
        private readonly Func<string, bool> _Filter;

        /// <summary>
        /// Property for path from where to load files.
        /// </summary>
        private string Path
        {
            get
            {
                return this._Path;
            }
        }

        /// <summary>
        /// Property for expression by that sql-files to load are being filtered.
        /// </summary>
        private Func<string, bool> Filter
        {
            get
            {
                return this._Filter;
            }
        }

        ///<summary>
        /// Initializes a new instance of the <see cref="FolderScriptProvider"/> class to load all sql-files
        /// from a given path.
        ///</summary>
        ///<param name="path">Filesystem path from which sql-files should be loaded.</param>
        public FolderScriptProvider(string path)
            : this(path, fileName => true)
        {
        }

        ///<summary>
        /// Initializes a new instance of the <see cref="FolderScriptProvider"/> class to load by an expression filtered 
        /// sql-files from a given path.
        ///</summary>
        ///<param name="path">Filesystem path from which sql-files should be loaded.</param>
        ///<param name="filter">Expression by which sql-files to load could be filtered.</param>
        public FolderScriptProvider(string path, Func<string, bool> filter)
        {
            if (string.IsNullOrEmpty(path)) throw new ArgumentNullException("path");
            if (!Directory.Exists(path)) throw new DirectoryNotFoundException();

            this._Path = path;
            this._Filter = filter;
        }

        /// <summary>
        /// Gets all sql scripts that should be executed from a given path that match the exetension .sql.
        /// </summary>
        public IEnumerable<SqlScript> GetScripts()
        {
            return Directory.GetFiles(this.Path, FolderScriptProvider.FILE_SEARCH_PATTERN)
                .Where(this.Filter)
                .OrderBy(file => file)
                .Select(file => new SqlScript(file, File.ReadAllText(file, Encoding.UTF8)))
                .ToList();
        }
    }
}